package com.alibaba.csp.sentinel.dashboard.rule.nacos;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.RuleEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.SystemRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleHandler;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Nacos服务
 *
 * @author slf
 * @since 2024/4/12 21:33
 **/
@Component
public class NacosServer implements DynamicRuleHandler {

  public static Map<Class, String> DATA_FIX = new HashMap<>(16);
  public static String PRE = "sentinel-";

  static {
    DATA_FIX.put(GatewayFlowRuleEntity.class, "-GW-FLOW");
    DATA_FIX.put(ApiDefinitionEntity.class, "-GW-API");
    DATA_FIX.put(FlowRuleEntity.class, "-FLOW");
    DATA_FIX.put(DegradeRuleEntity.class, "-DEGRADE");
    DATA_FIX.put(AuthorityRuleEntity.class, "-AUTHORITY");
    DATA_FIX.put(ParamFlowRuleEntity.class, "-PARAM");
    DATA_FIX.put(SystemRuleEntity.class, "-SYSTEM");
  }

  private final Logger log = LoggerFactory.getLogger(NacosServer.class);
  @Resource
  private ConfigService configService;
  /**
   * 所在组
   */
  @Value("${nacos.group:sentinel}")
  private String group;

  public <T extends RuleEntity> void publish(String app, Class<T> clazz, List<T> rules) {
    try {
      configService.publishConfig(PRE + app + DATA_FIX.get(clazz),
          group, JSON.toJSONString(rules));
    } catch (NacosException e) {
      log.error("Nacos 推送信息失败：{}:{}:{}:", app, clazz, rules, e);
    }
  }

  public <T extends RuleEntity> ArrayList<T> getRules(String app, Class<T> clazz) {
    String rules;
    try {
      rules = configService.getConfig(PRE + app + DATA_FIX.get(clazz),
          group, 3000);
    } catch (NacosException e) {
      log.error("Nacos 获取信息失败:{}：{}", app, clazz, e);
      return new ArrayList<>();
    }
    return (ArrayList<T>) JSON.parseArray(rules, clazz);
  }

}
